// Copyright (C) joyinter
// All rights reserved.
// 
// Author : Jiang Li
// Date   : 2004-11-11

#include "stdafx.h"
#include "svr_asyncexec.h"
#include "svr_asyncobj.h"
#include "svr_server.h"
#include "svr_showinfo.h"

namespace JoyServer
{

const int JOY_ASYNC_THREAD_MAX = 256;

// class CJoyAsyncWorker

void CJoyAsyncWorker::Execute(RequestType pAsyObj, void *, OVERLAPPED* ) throw()
{
    pAsyObj->Execute();
    pAsyObj->Release();
    -- m_executor->m_queuedCount;
}

// class CJoyAsyncExec

CJoyAsyncExec::CJoyAsyncExec()
{
    m_threadCount = 0;
    m_threadIncrement   = 16;
    m_server    = NULL;
}

CJoyAsyncExec::~CJoyAsyncExec()
{
}

void CJoyAsyncExec::ResizePool(int queuedCount)
{
    CJoyAutoCS gate(m_resizeLock);
    if(queuedCount > m_threadCount && m_threadCount < JOY_ASYNC_THREAD_MAX)
    {
        m_threadCount += m_threadIncrement;
        SetSize(m_threadCount);

        m_server->m_showInfo->QueueTimeColorText(InfoColor_Note,
            "resize thread pool. current thread count: %d.\n", m_threadCount);
    }
}

bool CJoyAsyncExec::Create(CJoyServer* pServer, int nThreadCount, int nIncrement)
{
    if(FAILED(Initialize(this, nThreadCount)))
    {
        return false;
    }

    m_threadCount       = nThreadCount;
    m_threadIncrement   = nIncrement;
    m_server    = pServer;

    return true;
}

bool CJoyAsyncExec::QueueObject(CJoyAsyncObject* asyObj)
{
    // caller should do addref.
    // asyObj->AddRef();

    int n = ++ m_queuedCount;
    if(n > m_threadCount && n <= JOY_ASYNC_THREAD_MAX)
    {
        ResizePool(n);
    }

    if(!QueueRequest(asyObj))
    {
        asyObj->Release();
        -- m_queuedCount;
        return false;
    }
    return true;
}

void CJoyAsyncExec::Destroy()
{
    m_server->m_showInfo->QueueTimeText("waiting for thread pool shutdown...\n");
    Shutdown(120000);
}

} // namespace JoyServer
